<?php
 /***************************************************************
 * Mor-MVC Framework, A framework that can easily let you build a powerful
 * and scalable web application based on PHP language,
 * this framewrok is a copy of the Zend Behavior Framework
 *  Copyright (C) 2010  Nabil Droussi <nabildroussi@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***************************************************************/
class FrontController
{
	private static $_instance = null;
	private $_templateDirectory = "";
	public function __construct()
	{
		$this->loadDependencies();
                $this->includeModels();
	}
	public static function getInstance()
	{
		if(self::$_instance == null)
			self::$_instance = new FrontController();
		return self::$_instance;
	}
	public function dispatch()
	{
		if(!isset($_GET['act']))
			$action = "index";
		else
			$action = $_GET['act'];
		if(!isset($_GET['cont']))
			$controller = "index";
		else
			$controller = $_GET['cont'];
		$action = strtolower($action);
		$controller = ucwords(strtolower($controller));
		
		if(!file_exists(Registry::getItem("INCLUDE_PATH")."/BLL/Controllers/{$controller}Controller.php"))
			throw new Exception(sprintf($this->getMessage("CONTROLLER_FILE_NOT_FOUND","File % not found"),Registry::getItem("ABSOLUTE_PATH")."/BLL/Controllers/{$controller}Controller.php"));
			
		include("BLL/Controllers/{$controller}Controller.php");
		if(!class_exists("{$controller}Controller"))
			throw new Exception(sprintf($this->getMessage("CONTROLLER_CLASS_NOT_FOUND","Class %s not found"),"{$controller}Controller"));
		$contName = "{$controller}Controller";
		$actionName = $action."Action";
		$cont = new $contName();
		if(!($cont instanceof FrontControllerAction))
			throw new Exception(sprintf($this->getMessage("INVALID_CONTROLLER_INHERITANCE","function %s not found"),"{$controller}Controller"));
		if(!method_exists($cont,$actionName))
			throw new Exception(sprintf($this->getMessage("ACTION_FUNCTION_NOT_FOUND","function %s not found"),"{$actionName}","{$controller}Controller"));

                $cont->setActionName($action);
		$cont->setControllerName($controller);
		$cont->init();
		$cont->$actionName();
		$cont->setTemplateDirectory($this->_templateDirectory);
		$cont->preDispatch();
		$cont->parse();
	}
	private function getMessage($msg, $default)
	{
		if(isset($msg))
			return LocalLanguage::getErrorMessage($msg);
		else
			return $default;
	}
	private function loadDependencies()
	{
		$files = array();
		$files[] = "misc/languages/LocalLanguage.php";
		$files[] = "misc/Registry.php";
		$files[] = "misc/HttpRequest.php";
		$files[] = "misc/FrontControllerAction.php";
                $files[] = "DAL/CommandExecutor.php";
		foreach($files as $file)
		{
			require_once($file);
		}
	}
        private function includeModels()
        {
            $modelsDirectory = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR."BLL".DIRECTORY_SEPARATOR."models";
            $directoryPointer = opendir($modelsDirectory);
            if(!$directoryPointer)
                throw new Exception("Cannot open models directory.");

            while($file = readdir($directoryPointer))
            {
                if($file != "." && $file != "..")
                {
                    if(substr($file,strrpos($file,".")+1) == "php")
                    {
                        require_once($modelsDirectory."/".$file);
                    }
                }
            }
        }
	public function setIncludePath($includePath)
	{
		Registry::addItem("INCLUDE_PATH",$includePath);
	}
	public function setTemplatePath($templatesPath)
	{
		Registry::addItem("TEMPLATE_PATH",$templatesPath);
	}
	public function setAbsolutePath($absolutePath)
	{
		Registry::addItem("ABSOLUTE_PATH",$absolutePath);
	}
	public function setTemplateDirectory($directory)
	{
		$this->_templateDirectory = $directory;
	}
}
?>